using Microsoft.Extensions.Logging;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Infrastructure.Data;

namespace SumerCoreDevOps.Infrastructure.Identity;

/// <summary>
/// 用户操作日志管理器
/// </summary>
public class UserOperationLogManager
{
    private readonly FreeSQLProvider _dbProvider;
    private readonly ILogger<UserOperationLogManager> _logger;

    public UserOperationLogManager(FreeSQLProvider dbProvider, ILogger<UserOperationLogManager> logger)
    {
        _dbProvider = dbProvider;
        _logger = logger;
    }

    /// <summary>
    /// 记录用户操作日志
    /// </summary>
    public async Task<UserOperationLog> LogOperationAsync(
        string operationType,
        long? userId = null,
        string? username = null,
        string? targetType = null,
        long? targetId = null,
        string? targetName = null,
        string? description = null,
        string? details = null,
        string status = "Success",
        string? errorMessage = null,
        string? ipAddress = null,
        string? userAgent = null,
        string? requestPath = null,
        string logLevel = "Info")
    {
        var log = new UserOperationLog
        {
            UserId = userId,
            Username = username,
            OperationType = operationType,
            TargetType = targetType,
            TargetId = targetId,
            TargetName = targetName,
            Description = description,
            Details = details,
            Status = status,
            ErrorMessage = errorMessage,
            IpAddress = ipAddress,
            UserAgent = userAgent,
            RequestPath = requestPath,
            LogLevel = logLevel,
            CreatedAt = DateTime.UtcNow
        };

        await _dbProvider.Orm.Insert(log).ExecuteAffrowsAsync();

        if (status == "Failed")
        {
            _logger.LogWarning("用户操作失败: UserId={UserId}, Operation={Operation}, Error={Error}",
                userId, operationType, errorMessage);
        }
        else
        {
            _logger.LogDebug("记录用户操作: UserId={UserId}, Operation={Operation}", userId, operationType);
        }

        return log;
    }

    /// <summary>
    /// 记录登录操作
    /// </summary>
    public async Task LogLoginAsync(
        long? userId,
        string username,
        bool success,
        string? ipAddress = null,
        string? userAgent = null,
        string? errorMessage = null)
    {
        await LogOperationAsync(
            operationType: "Login",
            userId: userId,
            username: username,
            description: success ? "用户登录成功" : "用户登录失败",
            status: success ? "Success" : "Failed",
            errorMessage: errorMessage,
            ipAddress: ipAddress,
            userAgent: userAgent,
            logLevel: success ? "Info" : "Warning"
        );
    }

    /// <summary>
    /// 记录登出操作
    /// </summary>
    public async Task LogLogoutAsync(
        long userId,
        string username,
        string? ipAddress = null)
    {
        await LogOperationAsync(
            operationType: "Logout",
            userId: userId,
            username: username,
            description: "用户登出",
            ipAddress: ipAddress,
            logLevel: "Info"
        );
    }

    /// <summary>
    /// 记录创建用户操作
    /// </summary>
    public async Task LogCreateUserAsync(
        long operatorId,
        string operatorName,
        long targetUserId,
        string targetUsername,
        string? ipAddress = null)
    {
        await LogOperationAsync(
            operationType: "CreateUser",
            userId: operatorId,
            username: operatorName,
            targetType: "User",
            targetId: targetUserId,
            targetName: targetUsername,
            description: $"创建用户: {targetUsername}",
            ipAddress: ipAddress,
            logLevel: "Info"
        );
    }

    /// <summary>
    /// 记录修改密码操作
    /// </summary>
    public async Task LogChangePasswordAsync(
        long userId,
        string username,
        bool success,
        string? ipAddress = null,
        string? errorMessage = null)
    {
        await LogOperationAsync(
            operationType: "ChangePassword",
            userId: userId,
            username: username,
            targetType: "User",
            targetId: userId,
            targetName: username,
            description: success ? "修改密码成功" : "修改密码失败",
            status: success ? "Success" : "Failed",
            errorMessage: errorMessage,
            ipAddress: ipAddress,
            logLevel: success ? "Info" : "Warning"
        );
    }

    /// <summary>
    /// 记录重置密码操作
    /// </summary>
    public async Task LogResetPasswordAsync(
        long operatorId,
        string operatorName,
        long targetUserId,
        string targetUsername,
        string? ipAddress = null)
    {
        await LogOperationAsync(
            operationType: "ResetPassword",
            userId: operatorId,
            username: operatorName,
            targetType: "User",
            targetId: targetUserId,
            targetName: targetUsername,
            description: $"管理员重置用户密码: {targetUsername}",
            ipAddress: ipAddress,
            logLevel: "Warning"
        );
    }

    /// <summary>
    /// 记录锁定用户操作
    /// </summary>
    public async Task LogLockUserAsync(
        long operatorId,
        string operatorName,
        long targetUserId,
        string targetUsername,
        string reason,
        string? ipAddress = null)
    {
        await LogOperationAsync(
            operationType: "LockUser",
            userId: operatorId,
            username: operatorName,
            targetType: "User",
            targetId: targetUserId,
            targetName: targetUsername,
            description: $"锁定用户: {targetUsername}, 原因: {reason}",
            ipAddress: ipAddress,
            logLevel: "Warning"
        );
    }

    /// <summary>
    /// 记录解锁用户操作
    /// </summary>
    public async Task LogUnlockUserAsync(
        long operatorId,
        string operatorName,
        long targetUserId,
        string targetUsername,
        string? ipAddress = null)
    {
        await LogOperationAsync(
            operationType: "UnlockUser",
            userId: operatorId,
            username: operatorName,
            targetType: "User",
            targetId: targetUserId,
            targetName: targetUsername,
            description: $"解锁用户: {targetUsername}",
            ipAddress: ipAddress,
            logLevel: "Info"
        );
    }

    /// <summary>
    /// 记录分配角色操作
    /// </summary>
    public async Task LogAssignRoleAsync(
        long operatorId,
        string operatorName,
        long targetUserId,
        string targetUsername,
        long roleId,
        string roleName,
        string? ipAddress = null)
    {
        await LogOperationAsync(
            operationType: "AssignRole",
            userId: operatorId,
            username: operatorName,
            targetType: "User",
            targetId: targetUserId,
            targetName: targetUsername,
            description: $"为用户 {targetUsername} 分配角色 {roleName}",
            details: $"{{\"RoleId\":{roleId},\"RoleName\":\"{roleName}\"}}",
            ipAddress: ipAddress,
            logLevel: "Info"
        );
    }

    /// <summary>
    /// 记录撤销角色操作
    /// </summary>
    public async Task LogRevokeRoleAsync(
        long operatorId,
        string operatorName,
        long targetUserId,
        string targetUsername,
        long roleId,
        string roleName,
        string? ipAddress = null)
    {
        await LogOperationAsync(
            operationType: "RevokeRole",
            userId: operatorId,
            username: operatorName,
            targetType: "User",
            targetId: targetUserId,
            targetName: targetUsername,
            description: $"撤销用户 {targetUsername} 的角色 {roleName}",
            details: $"{{\"RoleId\":{roleId},\"RoleName\":\"{roleName}\"}}",
            ipAddress: ipAddress,
            logLevel: "Info"
        );
    }

    /// <summary>
    /// 获取用户操作日志
    /// </summary>
    public async Task<List<UserOperationLog>> GetLogsByUserIdAsync(
        long userId,
        int limit = 100,
        int offset = 0)
    {
        return await _dbProvider.Orm.Select<UserOperationLog>()
            .Where(l => l.UserId == userId)
            .OrderByDescending(l => l.CreatedAt)
            .Skip(offset)
            .Take(limit)
            .ToListAsync();
    }

    /// <summary>
    /// 获取特定操作类型的日志
    /// </summary>
    public async Task<List<UserOperationLog>> GetLogsByOperationTypeAsync(
        string operationType,
        int limit = 100,
        int offset = 0)
    {
        return await _dbProvider.Orm.Select<UserOperationLog>()
            .Where(l => l.OperationType == operationType)
            .OrderByDescending(l => l.CreatedAt)
            .Skip(offset)
            .Take(limit)
            .ToListAsync();
    }

    /// <summary>
    /// 获取最近的操作日志
    /// </summary>
    public async Task<List<UserOperationLog>> GetRecentLogsAsync(
        int limit = 100,
        string? username = null,
        string? operationType = null,
        DateTime? startTime = null,
        DateTime? endTime = null)
    {
        var query = _dbProvider.Orm.Select<UserOperationLog>();

        if (!string.IsNullOrEmpty(username))
        {
            query = query.Where(l => l.Username == username);
        }

        if (!string.IsNullOrEmpty(operationType))
        {
            query = query.Where(l => l.OperationType == operationType);
        }

        if (startTime.HasValue)
        {
            query = query.Where(l => l.CreatedAt >= startTime.Value);
        }

        if (endTime.HasValue)
        {
            query = query.Where(l => l.CreatedAt <= endTime.Value);
        }

        return await query
            .OrderByDescending(l => l.CreatedAt)
            .Take(limit)
            .ToListAsync();
    }

    /// <summary>
    /// 获取失败的操作日志
    /// </summary>
    public async Task<List<UserOperationLog>> GetFailedLogsAsync(
        int limit = 100,
        DateTime? startTime = null)
    {
        var query = _dbProvider.Orm.Select<UserOperationLog>()
            .Where(l => l.Status == "Failed");

        if (startTime.HasValue)
        {
            query = query.Where(l => l.CreatedAt >= startTime.Value);
        }

        return await query
            .OrderByDescending(l => l.CreatedAt)
            .Take(limit)
            .ToListAsync();
    }

    /// <summary>
    /// 获取操作统计信息
    /// </summary>
    public async Task<Dictionary<string, long>> GetOperationStatisticsAsync(
        DateTime? startTime = null,
        DateTime? endTime = null)
    {
        var query = _dbProvider.Orm.Select<UserOperationLog>();

        if (startTime.HasValue)
        {
            query = query.Where(l => l.CreatedAt >= startTime.Value);
        }

        if (endTime.HasValue)
        {
            query = query.Where(l => l.CreatedAt <= endTime.Value);
        }

        var results = await query
            .GroupBy(l => l.OperationType)
            .ToListAsync(g => new { g.Key, Count = g.Count() });

        return results.ToDictionary(r => r.Key, r => (long)r.Count);
    }

    /// <summary>
    /// 清理旧日志（保留指定天数的日志）
    /// </summary>
    public async Task<long> CleanupOldLogsAsync(int retentionDays = 90)
    {
        var cutoffDate = DateTime.UtcNow.AddDays(-retentionDays);

        var deleted = await _dbProvider.Orm.Delete<UserOperationLog>()
            .Where(l => l.CreatedAt < cutoffDate)
            .ExecuteAffrowsAsync();

        if (deleted > 0)
        {
            _logger.LogInformation("清理旧的用户操作日志: Count={Count}, RetentionDays={Days}", deleted, retentionDays);
        }

        return deleted;
    }
}
